/**
 * 
 */
package wpmp.security.client.internal;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import wpmp.utils.Statics;

/**
 * @author Wayne.Wang<5waynewang@gmail.com>
 * @since 1:59:40 PM Dec 4, 2013
 */
public class SecurityUtils {

	/**
	 * 获取cookie值
	 * 
	 * @param req
	 * @param name
	 * @return
	 */
	private static String getCookieValue(HttpServletRequest req, String name) {
		final Cookie[] cookies = req.getCookies();
		if (ArrayUtils.isEmpty(cookies)) {
			return null;
		}
		for (Cookie cookie : cookies) {
			if (StringUtils.equals(cookie.getName(), name)) {
				return cookie.getValue();
			}
		}
		return null;
	}

	/**
	 * 清除cookie
	 * 
	 * @param req
	 * @param resp
	 * @param name
	 */
	private static void clearCookie(HttpServletRequest req, HttpServletResponse resp, String name) {
		final Cookie[] cookies = req.getCookies();
		if (ArrayUtils.isEmpty(cookies)) {
			return;
		}
		for (Cookie cookie : cookies) {
			if (name.equals(cookie.getName())) {
				cookie.setMaxAge(0);
				cookie.setValue(null);
				resp.addCookie(cookie);
			}
		}
	}

	public static void setLoginNameToCookie(HttpServletResponse resp, String loginName) {
		setLoginNameToCookie(resp, loginName, null);
	}

	/**
	 * 设置 loginName 到 cookie
	 * 
	 * @param resp
	 * @param loginName
	 * @param expDays 失效天数
	 */
	public static void setLoginNameToCookie(HttpServletResponse resp, String loginName, Integer expDays) {
		final Cookie cookie = new Cookie(Statics.LOGIN_NAME, loginName);
		cookie.setMaxAge(expDays == null ? -1 : (expDays * 60 * 60 * 1000));
		resp.addCookie(cookie);
	}

	/**
	 * 获取cookie中的loginName值
	 * 
	 * @param req
	 * @return
	 */
	public static String getLoginNameFromCookie(HttpServletRequest req) {
		return getCookieValue(req, Statics.LOGIN_NAME);
	}

	/**
	 * 清除loginName
	 * 
	 * @param req
	 * @param resp
	 */
	public static void clearLoginName(HttpServletRequest req, HttpServletResponse resp) {
		clearCookie(req, resp, Statics.LOGIN_NAME);
	}

	public static void setSecurityIdToCookie(HttpServletResponse resp, String securityId) {
		setSecurityIdToCookie(resp, securityId, null);
	}

	/**
	 * 设置sid
	 * 
	 * @param resp
	 * @param securityId
	 * @param expDays 失效天数
	 */
	public static void setSecurityIdToCookie(HttpServletResponse resp, String securityId, Integer expDays) {
		resp.addCookie(createSecurityCookie(securityId, expDays));
	}

	static Cookie createSecurityCookie(String securityId, Integer expDays) {
		final Cookie cookie = new Cookie(Statics.SECURITY_ID, securityId);
		// 如果不设置该值，则Cookie只在当前会话内有效，即在用户关闭浏览器之前有效，而且这些Cookie不会保存到磁盘上。
		// 若生存时间为负值，代表浏览器关闭Cookie即消失。
		// 生存时间为0，代表删除Cookie。
		// 生存时间为正数，代表Cookie存在多少秒。
		cookie.setMaxAge(expDays == null ? -1 : (expDays * 60 * 60 * 1000));
		return cookie;
	}

	/**
	 * 获取sid
	 * 
	 * @param req
	 * @return
	 */
	public static String getSecurityId(HttpServletRequest req) {
		// 先从session中获取
		final String securityId = (String) req.getSession().getAttribute(Statics.SECURITY_ID);
		if (StringUtils.isNotBlank(securityId)) {
			return securityId;
		}

		// 再从cookie中获取
		return getCookieValue(req, Statics.SECURITY_ID);
	}

	/**
	 * 获取sid并设置
	 * 
	 * @param req
	 * @param resp
	 * @return
	 */
	public static String getAndSetSecurityId(HttpServletRequest req, HttpServletResponse resp) {
		String securityId;

		// 优先 request parameter
		securityId = req.getParameter(Statics.SECURITY_ID);
		if (StringUtils.isBlank(securityId)) {

			// 获取不到再从session 和 cookie中获取
			securityId = getSecurityId(req);
			if (StringUtils.isNotBlank(securityId)) {
				return securityId;
			}

			return null;
		}

		if (resp != null) {
			// 直接存至cookie中
			setSecurityIdToCookie(resp, securityId);
		}
		// 放入session
		req.getSession().setAttribute(Statics.SECURITY_ID, securityId);

		return securityId;

	}

	/**
	 * 清除sid
	 * 
	 * @param req
	 * @param resp
	 */
	public static void clearSecurityId(HttpServletRequest req, HttpServletResponse resp) {
		// 清除session中的数据
		req.getSession().removeAttribute(Statics.SECURITY_ID);
		// 清除cookie中的数据
		clearCookie(req, resp, Statics.SECURITY_ID);
	}
}
